# -*- coding: utf-8 -*-
# written by Konstantin A. Zolotukhin (masted@gmail.com)
# 2008.
# This modules is free software in terms of the BSD licence. That means
# that you can do anything with it except removing this license or
# the above copyright notice. There is NO WARRANTY of any kind.
"""Реализация представлений.
"""

__all__ = ['View', 'BaseView', 'ViewFactory', 'views_dispatcher']

import logging

log = logging.getLogger(__name__)

class View(object):
    """Определение интерфейса представлений
    """
        
    def __init__(self):
        self._data = None
    
    def generate_context(self):
        """Генерация контекста должна быть реализована этим методом
        """
    
    def set_data(self, data):
        """Установка данных
        """
    
    def get_data(self):
        """Получение данных
        """
    
    def view(self):
        """Отображение должно быть реализовано в этом методе.
        """
    
    class DoesNotExist(Exception):
        """Вызывается в случае, если искомый View не существует
        """

class BaseView(View):
    
    def __init__(self):
        super(BaseView, self).__init__()
    
    def set_data(self, data):
        self._data = data
    
    def get_data(self):
        return self._data
    
    def view(self):
        pass

class ViewFactory(object):
    
    def __init__(self):
        self._views = {}
        
    def add_views(self, views):
        """ 
            Регистрирует множество вьюх 
        """
        
        assert isinstance(views, dict), "`views` must be a dict"
    
        self._views.update(views)
          
    def add_view(self, view_name, view):
        """ 
            Регистрирует одну вьюху.
            Получает в качестве аргументов имя вьюхи и класс 
        """
        
        assert isinstance(view_name, (str, unicode)), "`view_name` must be a string or unicode"
        assert issubclass(view, View), '`view` must be a subclass of View'
        
        self._views[view_name] = view
    
    def get_view(self, view_name):
        
        assert isinstance(view_name, (str, unicode)), "`view_name` must be a string or unicode"
        
        try:
            view = self._views[view_name]
        except KeyError:
            raise View.DoesNotExist, 'view "%(view_name)s" does not exist' % {'view_name' : view_name}
        
        view_instance = view()
        return view_instance

def views_dispatcher(view_factory, request_type, data):
    """ 
        Простой диспетчер представлений реализованный в виде функции, 
        получает в качестве аргументов фабрику представлений,
        тип запроса и данные для отображения.
    """
    
    log = logging.getLogger('%s.views_dispatcher' % __name__)
    
    log.debug('get request_type: "%s" ' % request_type)
    log.debug('lookup view for request_type')
    
    view = view_factory.get_view(request_type)
    
    log.debug('view finded: %s' % view)
    
    view.set_data(data)
    return view.view()

